using UnityEngine;

public class RectangleIndicator : IAttackIndicator
{
    private float m_Width = 3f;
    private float m_Length = 6f;
    private float m_FillAmount = 1f;
    private Color m_FillColor = Color.white;
    private Vector3 m_FillDirection = Vector3.forward;
    private Material m_MaterialInstance;

    private GameObject m_IndicatorObject;
    private MeshFilter m_MeshFilter;
    private MeshRenderer m_MeshRenderer;

    private bool m_IsDestroyed = false;
    private bool m_IsUpdating = false;

    public float Width
    {
        get => m_Width;
        set => m_Width = Mathf.Clamp(value, 0.1f, 20f);
    }

    public float Length
    {
        get => m_Length;
        set => m_Length = Mathf.Clamp(value, 0.1f, 20f);
    }

    public void Initialize(GameObject parent, Material material)
    {
        m_IndicatorObject = new GameObject("RectangleIndicator");
        m_IndicatorObject.AddComponent<RectTransform>();
        m_IndicatorObject.transform.SetParent(parent.transform, false);
        m_IndicatorObject.transform.localPosition = Vector3.zero;
        m_IndicatorObject.transform.localRotation = Quaternion.identity;

        m_MeshFilter = m_IndicatorObject.AddComponent<MeshFilter>();
        m_MeshRenderer = m_IndicatorObject.AddComponent<MeshRenderer>();

#if UNITY_EDITOR
        if (!Application.isPlaying)
        {
            m_MeshRenderer.sharedMaterial = material;
            m_MaterialInstance = m_MeshRenderer.sharedMaterial;
        }
        else
#endif
        {
            m_MaterialInstance = new Material(material);
            m_MeshRenderer.material = m_MaterialInstance;
        }

        m_MeshRenderer.sortingOrder = 3000;
        m_IsDestroyed = false;
        UpdateMesh();
    }

    public void UpdateParams()
    {
        if (m_IsDestroyed || m_IsUpdating) return;
        m_IsUpdating = true;
        try { UpdateMesh(); }
        finally { m_IsUpdating = false; }
    }

    public void SetFillAmount(float fillAmount)
    {
        m_FillAmount = Mathf.Clamp01(fillAmount);
        if (!m_IsDestroyed && !m_IsUpdating) UpdateMesh();
    }

    public void SetFillColor(Color color)
    {
        m_FillColor = color;
        if (m_MaterialInstance != null && !m_IsDestroyed)
        {
#if UNITY_EDITOR
            if (!Application.isPlaying) m_MeshRenderer.sharedMaterial.color = m_FillColor;
            else
#endif
                m_MaterialInstance.color = m_FillColor;
        }
    }

    public void SetFillDirection(Vector3 direction)
    {
        m_FillDirection = direction.normalized;
        if (!m_IsDestroyed && !m_IsUpdating) UpdateMesh();
    }

    private void UpdateMesh()
    {
        if (m_MeshFilter == null || m_IndicatorObject == null || m_IsDestroyed) return;
        if (m_FillAmount <= 0.01f)
        {
            m_MeshFilter.mesh = null;
            return;
        }

        // ���㵱ǰ��䳤��
        float currentLength = m_Length * m_FillAmount;

        // ���㴹ֱ������ȷ�ķ�����
        Vector3 right = Vector3.Cross(Vector3.up, m_FillDirection).normalized;
        if (right.sqrMagnitude < 0.01f)
        {
            // ����������Ϸ���ƽ�У�ʹ�ñ��÷���
            right = Vector3.Cross(Vector3.forward, m_FillDirection).normalized;
            if (right.sqrMagnitude < 0.01f)
            {
                right = Vector3.Cross(Vector3.right, m_FillDirection).normalized;
            }
        }

        // �������Ͱ볤����
        Vector3 halfW = right * m_Width * 0.5f;
        Vector3 filledHalfL = m_FillDirection * currentLength * 0.5f;
        Vector3 unfilledHalfL = m_FillDirection * (m_Length - currentLength) * 0.5f;

        // �����ĸ��ǵ�
        Vector3[] vertices = new Vector3[4]
        {
            -halfW - filledHalfL, // ���£���䲿�֣�
            -halfW + filledHalfL, // ���ϣ���䲿�֣�
            halfW + filledHalfL,  // ���ϣ���䲿�֣�
            halfW - filledHalfL   // ���£���䲿�֣�
        };

        // ������������������������ɾ��Σ�
        int[] triangles = { 0, 1, 2, 0, 2, 3 };

        // UV���꣨��������ӳ�䣩
        Vector2[] uvs = new Vector2[4]
        {
            new Vector2(0, 0), // ����
            new Vector2(0, 1), // ����
            new Vector2(1, 1), // ����
            new Vector2(1, 0)  // ����
        };

        Mesh mesh = new Mesh();
        mesh.vertices = vertices;
        mesh.triangles = triangles;
        mesh.uv = uvs;
        mesh.RecalculateNormals();
        mesh.RecalculateBounds();
        m_MeshFilter.mesh = mesh;

        // �������
        Logger.Log($"Rectangle mesh updated: width={m_Width}, length={m_Length}, fill={m_FillAmount}");
        Logger.Log($"- Vertices: {vertices[0]}, {vertices[1]}, {vertices[2]}, {vertices[3]}");
    }

    public void Show()
    {
        if (m_IndicatorObject != null && !m_IsDestroyed)
            m_IndicatorObject.SetActive(true);
    }

    public void Hide()
    {
        if (m_IndicatorObject != null && !m_IsDestroyed)
            m_IndicatorObject.SetActive(false);
    }

    public void CleanUp()
    {
        if (m_IndicatorObject != null)
        {
            if (Application.isPlaying) Object.Destroy(m_IndicatorObject);
            else Object.DestroyImmediate(m_IndicatorObject);
            m_IsDestroyed = true;
        }
    }
}
